﻿using System;
using GalaSoft.MvvmLight.Messaging;

namespace Songhay.Mvvm.Models
{
    /// <summary>
    /// Defines the conventional MVVM Light Navigation Message.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <remarks>
    /// This class supports the parsing Navigation Data
    /// where the Relative URI is of the form
    /// 
    /// <code>
    ///     /{key}/{id}
    /// </code>
    /// 
    /// This is the form that emerges
    /// from Page Navigation bookmarks (<c>#/{key}/{id}</c>),
    /// a URI fragment (or hash) that, by convention,
    /// only uses forward slashes.
    /// These forward slashes are used to split the bookmark
    /// into a string array, setting <c>RelativeUriSegments</c>.
    /// </remarks>
    public class LightNavigationMessage<T> : GenericMessage<T>, ILightMessage
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="LightNavigationMessage&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="messageContent">Content of the message.</param>
        public LightNavigationMessage(T messageContent)
            : base(messageContent)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="LightNavigationMessage&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <param name="messageContent">Content of the message.</param>
        public LightNavigationMessage(string location, T messageContent)
            : base(messageContent)
        {
            this.processLocation(location);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="LightNavigationMessage&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <param name="messageSender">The message sender.</param>
        /// <param name="messageContent">Content of the message.</param>
        public LightNavigationMessage(string location, object messageSender, T messageContent)
            : base(messageSender, messageContent)
        {
            this.processLocation(location);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="LightNavigationMessage&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <param name="messageSender">The message sender.</param>
        /// <param name="messageTarget">The message target.</param>
        /// <param name="messageContent">Content of the message.</param>
        public LightNavigationMessage(string location, object messageSender, object messageTarget, T messageContent)
            : base(messageSender, messageTarget, messageContent)
        {
            this.processLocation(location);
        }

        /// <summary>
        /// Gets or sets a value indicating whether this instance has a well-formed URI string.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance has a well-formed URI string; otherwise, <c>false</c>.
        /// </value>
        public bool HasWellFormedUriString { get; private set; }

        /// <summary>
        /// Gets or sets the relative URI segments.
        /// </summary>
        /// <value>The relative URI segments.</value>
        public string[] RelativeUriSegments{get; private set;}

        /// <summary>
        /// Gets or sets the source.
        /// </summary>
        /// <value>The source.</value>
        public LightMessageSource Source { get; set; }

        /// <summary>
        /// Gets or sets the target location.
        /// </summary>
        /// <value>The target location.</value>
        public string TargetLocation { get; set; }

        /// <summary>
        /// Gets or sets the target absolute URI.
        /// </summary>
        /// <value>The target absolute URI.</value>
        public Uri TargetUri { get; set; }

        /// <summary>
        /// Gets or sets the unique id.
        /// </summary>
        /// <value>
        /// The unique id.
        /// </value>
        public string UniqueId { get; set; }

        void processLocation(string location)
        {
            if(string.IsNullOrEmpty(location)) return;

            this.HasWellFormedUriString = Uri.IsWellFormedUriString(location, UriKind.RelativeOrAbsolute);
            this.TargetUri = this.HasWellFormedUriString ? new Uri(location, UriKind.RelativeOrAbsolute) : null;
            if(this.TargetUri != null) this.TargetLocation = this.TargetUri.OriginalString;

            if(this.HasWellFormedUriString && !this.TargetUri.IsAbsoluteUri)
                this.RelativeUriSegments = this.TargetUri.OriginalString.Split('/');
        }
    }
}
